home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------------*/
- /* */
- /* */
- /* ------------ Bit-Bucket Software <no-Inc> */
- /* \ 10001101 / Writers and Distributors of */
- /* \ 011110 / No-Cost<no-tm> Software. */
- /* \ 1011 / */
- /* ------ */
- /* */
- /* Copyright (C) 1987, 1988, 1989 by Robert Hartman and Vincent Perriello */
- /* */
- /* */
- /* Zmodem routines used by Zsend and Zreceive */
- /* */
- /* */
- /* For complete details of the licensing restrictions, please refer */
- /* to the License agreement, which is published in its entirety in */
- /* the MAKEFILE and BT.C, and also contained in the file LICENSE.210. */
- /* */
- /* USE OF THIS FILE IS SUBJECT TO THE RESTRICTIONS CONTAINED IN THE */
- /* BINKLEYTERM LICENSING AGREEMENT. IF YOU DO NOT FIND THE TEXT OF */
- /* THIS AGREEMENT IN ANY OF THE AFOREMENTIONED FILES, OR IF YOU DO */
- /* NOT HAVE THESE FILES, YOU SHOULD IMMEDIATELY CONTACT THE AUTHORS */
- /* AT THE ADDRESSES LISTED BELOW. IN NO EVENT SHOULD YOU PROCEED TO */
- /* USE THIS FILE WITHOUT HAVING ACCEPTED THE TERMS OF THE */
- /* BINKLEYTERM LICENSING AGREEMENT, OR SUCH OTHER AGREEMENT AS YOU */
- /* ARE ABLE TO REACH WITH THE AUTHORS. */
- /* */
- /* */
- /* The Authors can be reached at the following addresses: */
- /* */
- /* Robert C. Hartman Vincent E. Perriello */
- /* Spark Software VEP Software */
- /* 427-3 Amherst Street 111 Carroll Street */
- /* CS2032, Suite 232 Naugatuck, CT 06770 */
- /* Nashua, NH 03061 */
- /* */
- /* FidoNet 1:132/101 FidoNet 1:141/491 */
- /* Data (603) 888-8179 Data (203) 729-7569 */
- /* */
- /* Please feel free to contact us at any time to share your comments */
- /* about our software and/or licensing policies. */
- /* */
- /* */
- /* This module is based largely on a similar module in OPUS-CBCS V1.03b. */
- /* The original work is (C) Copyright 1986, Wynn Wagner III. The original */
- /* authors have graciously allowed us to use their code in this work. */
- /* */
- /*--------------------------------------------------------------------------*/
-
-
- #include <conio.h>
-
- #ifdef __TURBOC__
- #include <alloc.h>
- #else
- #include <malloc.h>
- #endif
-
- #include "com.h"
- #include "xfer.h"
- #include "zmodem.h"
- #include "keybd.h"
- #include "sbuf.h"
- #include "sched.h"
- #include "externs.h"
- #include "prototyp.h"
-
-
- static int Rxtype; /* Type of header received */
-
- static char hex[] = "0123456789abcdef";
-
- /* Send a byte as two hex digits */
- #define Z_PUTHEX(i,c) {i=(c);SENDBYTE(hex[((i)&0xF0)>>4]);SENDBYTE(hex[(i)&0xF]);}
-
- /*--------------------------------------------------------------------------*/
- /* Private routines */
- /*--------------------------------------------------------------------------*/
- static int _Z_qk_read (void);
- static int _Z_GetBinaryHeader (unsigned char *);
- static int _Z_32GetBinaryHeader (unsigned char *);
- static int _Z_GetHexHeader (unsigned char *);
- static int _Z_GetHex (void);
- static int _Z_TimedRead (void);
- static long _Z_PullLongFromHeader (unsigned char *);
-
- void z_message (s)
- byte *s;
- {
- if (fullscreen && un_attended)
- {
- if (s)
- {
- sb_move (filewin, 2, 27);
- sb_puts (filewin, s);
- }
- sb_puts (filewin, " ");
- sb_show ();
- }
- else
- {
- gotoxy (locate_x + 20, locate_y);
- if (s)
- {
- cputs (s);
- }
- cputs (" ");
- }
- }
-
- void z_log (s)
- char *s;
- {
- word x, y;
-
- z_message (s);
-
- x = locate_x;
- y = locate_y;
- status_line (s); /* also does disk file
- * logging */
- locate_x = x;
- locate_y = y;
- }
-
- void show_loc (l, w)
- unsigned long l;
- unsigned int w;
- {
- char j[100];
-
- if (fullscreen && un_attended)
- {
- sb_move (filewin, 2, 37);
- sprintf (j, "Ofs=%ld Retries=%d ", l, w);
- sb_puts (filewin, j);
- sb_show ();
- }
- else
- {
- gotoxy (locate_x + 35, locate_y);
- cprintf ("Ofs=%ld Retries=%d ", l, w);
- }
- }
-
- char *zalloc ()
- {
- byte *sptr;
-
- sptr = malloc (WAZOOMAX + 16);
- if (!sptr)
- {
- status_line ("!Z-MEMOVFL");
- adios (2);
- }
- return sptr;
- }
-
- /*--------------------------------------------------------------------------*/
- /* Z GET BYTE */
- /* Get a byte from the modem; */
- /* return TIMEOUT if no read within timeout tenths, */
- /* return RCDO if carrier lost */
- /*--------------------------------------------------------------------------*/
- /*PLF Sat 05-06-1989 05:47:32; heavy clean up job. */
- int Z_GetByte (tenths)
- int tenths;
- {
- long timeout;
-
- if(CHAR_AVAIL())
- return MODEM_IN();
-
- timeout = timerset(tenths * 10);
-
- do{
- if(CHAR_AVAIL())
- return MODEM_IN();
- if(!CARRIER)
- return RCDO;
- if(got_ESC()) return -1;
- time_release();
- }
- while(!timeup(timeout));
-
- return TIMEOUT;
- }
-
- /*--------------------------------------------------------------------------*/
- /* QK_READ (like Z_GetByte, but assumes the time to be Rxtimeout) */
- /* Get a byte from the modem; */
- /* return TIMEOUT if no read within timeout tenths, */
- /* return RCDO if carrier lost */
- /*--------------------------------------------------------------------------*/
- /*PLF Sat 05-06-1989 05:51:11; Turned it into a macro. */
- #define _Z_qk_read() Z_GetByte(Rxtimeout)
-
- /*--------------------------------------------------------------------------*/
- /* Z PUT STRING */
- /* Send a string to the modem, processing for \336 (sleep 1 sec) */
- /* and \335 (break signal, ignored) */
- /*--------------------------------------------------------------------------*/
- void Z_PutString (s)
- register unsigned char *s;
- {
- register int c;
-
- while (*s)
- {
- switch (c = *s++)
- {
- case '\336':
- big_pause (2);
- case '\335':
- /* Should send a break on this */
- break;
- default:
- SENDBYTE ((unsigned char) c);
- } /* switch */
-
- } /* while */
-
- Z_UncorkTransmitter (); /* Make sure all is well */
- } /* Z_PutString */
-
- /*--------------------------------------------------------------------------*/
- /* Z SEND HEX HEADER */
- /* Send ZMODEM HEX header hdr of type type */
- /*--------------------------------------------------------------------------*/
- void Z_SendHexHeader (type, hdr)
- unsigned int type;
- register unsigned char *hdr;
- {
- register int n;
- register int i;
- register word crc;
-
- Z_UncorkTransmitter (); /* Get our transmitter going */
-
- SENDBYTE (ZPAD);
- SENDBYTE (ZPAD);
- SENDBYTE (ZDLE);
- SENDBYTE (ZHEX);
- Z_PUTHEX (i, type);
-
- Crc32t = 0;
- crc = Z_UpdateCRC (type, 0);
- for (n = 4; --n >= 0;)
- {
- Z_PUTHEX (i, (*hdr));
- crc = Z_UpdateCRC (((unsigned short) (*hdr++)), crc);
- }
- Z_PUTHEX (i, (crc >> 8));
- Z_PUTHEX (i, crc);
-
- /* Make it printable on remote machine */
- SENDBYTE ('\r');
- SENDBYTE ('\n');
-
- /* Uncork the remote in case a fake XOFF has stopped data flow */
- if (type != ZFIN && type != ZACK)
- SENDBYTE (021);
-
- if (!CARRIER)
- CLEAR_OUTBOUND ();
- #ifdef OS_2 /*PLF Sat 05-06-1989 08:32:24 */
- com_wait();
- #endif
- } /* Z_SendHexHeader */
-
- /*--------------------------------------------------------------------------*/
- /* Z UNCORK TRANSMITTER */
- /* Wait a reasonable amount of time for transmitter buffer to clear. */
- /* When it does, or when time runs out, turn XON/XOFF off then on. */
- /* This should release a transmitter stuck by line errors. */
- /*--------------------------------------------------------------------------*/
-
- void Z_UncorkTransmitter ()
- {
- long t, timerset ();
-
- if (!OUT_EMPTY ())
- {
- t = timerset (5 * Rxtimeout); /* Wait for silence */
- while (!timeup (t) && !OUT_EMPTY () && CARRIER)
- time_release (); /* Give up slice while
- * waiting */
- }
- XON_DISABLE (); /* Uncork the transmitter */
- XON_ENABLE ();
- }
-
-
- /*--------------------------------------------------------------------------*/
- /* Z GET HEADER */
- /* Read a ZMODEM header to hdr, either binary or hex. */
- /* On success, set Zmodem to 1 and return type of header. */
- /* Otherwise return negative on error */
- /*--------------------------------------------------------------------------*/
- int Z_GetHeader (hdr)
- byte *hdr;
- {
-
- register int c;
- register int n;
- int cancount;
-
- n = cur_baud; /* Max characters before
- * start of frame */
- cancount = 5;
-
- Again:
-
- if (got_ESC ())
- {
- send_can ();
- z_log (KBD_msg);
- return ZCAN;
- }
-
- Rxframeind = Rxtype = 0;
-
- switch (c = _Z_TimedRead ())
- {
- case ZPAD:
- case ZPAD | 0200:
- /*-----------------------------------------------*/
- /* This is what we want. */
- /*-----------------------------------------------*/
- break;
-
- case RCDO:
- case TIMEOUT:
- goto Done;
-
- case CAN:
-
- GotCan:
-
- if (--cancount <= 0)
- {
- c = ZCAN;
- goto Done;
- }
- switch (c = Z_GetByte (1))
- {
- case TIMEOUT:
- goto Again;
-
- case ZCRCW:
- c = ERROR;
- /* fallthrough... */
-
- case RCDO:
- goto Done;
-
- case CAN:
- if (--cancount <= 0)
- {
- c = ZCAN;
- goto Done;
- }
- goto Again;
- }
- /* fallthrough... */
-
- default:
-
- Agn2:
-
- if (--n <= 0)
- {
- z_log (FUBAR_msg);
- return ERROR;
- }
-
- if (c != CAN)
- cancount = 5;
- goto Again;
-
- } /* switch */
-
- cancount = 5;
-
- Splat:
-
- switch (c = _Z_TimedRead ())
- {
- case ZDLE:
- /*-----------------------------------------------*/
- /* This is what we want. */
- /*-----------------------------------------------*/
- break;
-
- case ZPAD:
- goto Splat;
-
- case RCDO:
- case TIMEOUT:
- goto Done;
-
- default:
- goto Agn2;
-
- } /* switch */
-
-
- switch (c = _Z_TimedRead ())
- {
-
- case ZBIN:
- Rxframeind = ZBIN;
- Crc32 = 0;
- c = _Z_GetBinaryHeader (hdr);
- break;
-
- case ZBIN32:
- Crc32 = Rxframeind = ZBIN32;
- c = _Z_32GetBinaryHeader (hdr);
- break;
-
- case ZHEX:
- Rxframeind = ZHEX;
- Crc32 = 0;
- c = _Z_GetHexHeader (hdr);
- break;
-
- case CAN:
- goto GotCan;
-
- case RCDO:
- case TIMEOUT:
- goto Done;
-
- default:
- goto Agn2;
-
- } /* switch */
-
- Rxpos = _Z_PullLongFromHeader (hdr);
-
- Done:
-
- return c;
- } /* Z_GetHeader */
-
- /*--------------------------------------------------------------------------*/
- /* Z GET BINARY HEADER */
- /* Receive a binary style header (type and position) */
- /*--------------------------------------------------------------------------*/
- static int _Z_GetBinaryHeader (hdr)
- register unsigned char *hdr;
- {
- register int c;
- register unsigned int crc;
- register int n;
-
- if ((c = Z_GetZDL ()) & ~0xFF)
- return c;
- Rxtype = c;
- crc = Z_UpdateCRC (c, 0);
-
- for (n = 4; --n >= 0;)
- {
- if ((c = Z_GetZDL ()) & ~0xFF)
- return c;
- crc = Z_UpdateCRC (c, crc);
- *hdr++ = (unsigned char) (c & 0xff);
- }
- if ((c = Z_GetZDL ()) & ~0xFF)
- return c;
-
- crc = Z_UpdateCRC (c, crc);
- if ((c = Z_GetZDL ()) & ~0xFF)
- return c;
-
- crc = Z_UpdateCRC (c, crc);
- if (crc & 0xFFFF)
- {
- z_message (CRC_msg);
- return ERROR;
- }
-
- return Rxtype;
- } /* _Z_GetBinaryHeader */
-
-
- /*--------------------------------------------------------------------------*/
- /* Z GET BINARY HEADER with 32 bit CRC */
- /* Receive a binary style header (type and position) */
- /*--------------------------------------------------------------------------*/
- static int _Z_32GetBinaryHeader (hdr)
- register unsigned char *hdr;
- {
- register int c;
- register unsigned long crc;
- register int n;
-
- if ((c = Z_GetZDL ()) & ~0xFF)
- return c;
- Rxtype = c;
- crc = 0xFFFFFFFF;
- crc = Z_32UpdateCRC (c, crc);
-
- for (n = 4; --n >= 0;)
- {
- if ((c = Z_GetZDL ()) & ~0xFF)
- return c;
- crc = Z_32UpdateCRC (c, crc);
- *hdr++ = (unsigned char) (c & 0xff);
- }
-
- for (n = 4; --n >= 0;)
- {
- if ((c = Z_GetZDL ()) & ~0xFF)
- return c;
-
- crc = Z_32UpdateCRC (c, crc);
- }
-
- if (crc != 0xDEBB20E3)
- {
- z_message (CRC_msg);
- return ERROR;
- }
-
- return Rxtype;
- } /* _Z_32GetBinaryHeader */
-
- /*--------------------------------------------------------------------------*/
- /* Z GET HEX HEADER */
- /* Receive a hex style header (type and position) */
- /*--------------------------------------------------------------------------*/
- static int _Z_GetHexHeader (hdr)
- register unsigned char *hdr;
- {
- register int c;
- register unsigned int crc;
- register int n;
-
- if ((c = _Z_GetHex ()) < 0)
- return c;
- Rxtype = c;
- crc = Z_UpdateCRC (c, 0);
-
- for (n = 4; --n >= 0;)
- {
- if ((c = _Z_GetHex ()) < 0)
- return c;
- crc = Z_UpdateCRC (c, crc);
- *hdr++ = (unsigned char) c;
- }
-
- if ((c = _Z_GetHex ()) < 0)
- return c;
- crc = Z_UpdateCRC (c, crc);
- if ((c = _Z_GetHex ()) < 0)
- return c;
- crc = Z_UpdateCRC (c, crc);
- if (crc & 0xFFFF)
- {
- z_message (CRC_msg);
- return ERROR;
- }
- if (Z_GetByte (1) == '\r')
- Z_GetByte (1); /* Throw away possible cr/lf */
-
- return Rxtype;
- }
-
- /*--------------------------------------------------------------------------*/
- /* Z GET HEX */
- /* Decode two lower case hex digits into an 8 bit byte value */
- /*--------------------------------------------------------------------------*/
- static int _Z_GetHex ()
- {
- register int c, n;
-
- if ((n = _Z_TimedRead ()) < 0)
- return n;
- n -= '0';
- if (n > 9)
- n -= ('a' - ':');
- if (n & ~0xF)
- return ERROR;
-
- if ((c = _Z_TimedRead ()) < 0)
- return c;
- c -= '0';
- if (c > 9)
- c -= ('a' - ':');
- if (c & ~0xF)
- return ERROR;
-
- return ((n << 4) | c);
- }
-
- /*--------------------------------------------------------------------------*/
- /* Z GET ZDL */
- /* Read a byte, checking for ZMODEM escape encoding */
- /* including CAN*5 which represents a quick abort */
- /*--------------------------------------------------------------------------*/
- int Z_GetZDL ()
- {
- register int c;
-
- if ((c = _Z_qk_read ()) != ZDLE)
- return c;
-
- switch (c = _Z_qk_read ())
- {
- case CAN:
- return ((c = _Z_qk_read ()) < 0) ? c :
- ((c == CAN) && ((c = _Z_qk_read ()) < 0)) ? c :
- ((c == CAN) && ((c = _Z_qk_read ()) < 0)) ? c : (GOTCAN);
-
- case ZCRCE:
- case ZCRCG:
- case ZCRCQ:
- case ZCRCW:
- return (c | GOTOR);
-
- case ZRUB0:
- return 0x7F;
-
- case ZRUB1:
- return 0xFF;
-
- default:
- return (c < 0) ? c :
- ((c & 0x60) == 0x40) ? (c ^ 0x40) : ERROR;
-
- } /* switch */
- } /* Z_GetZDL */
-
- /*--------------------------------------------------------------------------*/
- /* Z TIMED READ */
- /* Read a character from the modem line with timeout. */
- /* Eat parity, XON and XOFF characters. */
- /*--------------------------------------------------------------------------*/
- static int _Z_TimedRead ()
- {
- register int c;
-
- for (;;)
- {
- if ((c = _Z_qk_read ()) < 0)
- return c;
-
- switch (c &= 0x7F)
- {
- case XON:
- case XOFF:
- continue;
-
- default:
- if (!(c & 0x60))
- continue;
-
- case '\r':
- case '\n':
- case ZDLE:
- return c;
- } /* switch */
-
- } /* for */
- } /* _Z_TimedRead */
-
- /*--------------------------------------------------------------------------*/
- /* Z LONG TO HEADER */
- /* Store long integer pos in Txhdr */
- /*--------------------------------------------------------------------------*/
- void Z_PutLongIntoHeader (pos)
- long pos;
- {
- #ifndef GENERIC
- /*PLF extern long *TXlong; Fri 05-05-1989 06:45:00 */
-
- /* *TXlong = pos; */
- *((long *) Txhdr) = pos; /*PLF Fri 05-05-1989 06:45:10 */
- #else
- Txhdr[ZP0] = pos;
- Txhdr[ZP1] = pos >> 8;
- Txhdr[ZP2] = pos >> 16;
- Txhdr[ZP3] = pos >> 24;
- #endif
- } /* Z_PutLongIntoHeader */
-
- /*--------------------------------------------------------------------------*/
- /* Z PULL LONG FROM HEADER */
- /* Recover a long integer from a header */
- /*--------------------------------------------------------------------------*/
- static long _Z_PullLongFromHeader (hdr)
- unsigned char *hdr;
- {
- #ifndef GENERIC
- /*PLF extern long *RXlong; somone was sleepy when they did this. */
-
- return (*((long *) Rxhdr)); /*PLF Fri 05-05-1989 06:42:41 */
- hdr; /*PLF Fri 05-05-1989 06:42:59 ; Trick to
- * keep /W3 happy */
- #else
- long l;
-
- l = hdr[ZP3];
- l = (l << 8) | hdr[ZP2];
- l = (l << 8) | hdr[ZP1];
- l = (l << 8) | hdr[ZP0];
- return l;
- #endif
- } /* _Z_PullLongFromHeader */
-
- /* END OF FILE: zmisc.c */